/*
* Copyright 2011 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/
package org.etherframework.mediator
{
	import flash.display.DisplayObject;
	
	import org.etherframework.IEther;
	import org.etherframework.common.Access;
	import org.etherframework.common.mediators.facade.IMediatorsFacade;
	import org.etherframework.core.bridge.IBridgeFacades;
	import org.etherframework.core.module.IModulePartFacade;
	
	[ExcludeClass]
	
	public class MediatorsFacade implements IMediatorsFacade
	{
		private var _part:IMediators;
		private var _owner:IBridgeFacades;
		
		public function MediatorsFacade(owner:IBridgeFacades, part:IMediators)
		{
			_owner = owner;
			_part = part;
		}
		
		public function prepare(ether:IEther):IModulePartFacade
		{
			return this;
		}
		
		public function createMediator(view:DisplayObject):IMediator
		{
			var result:IMediator;
			
			if (_owner.access == Access.GLOBAL)
			{
				result = _owner.parent.mediators.createMediator(view);
			}
			else
			{
				// As owner is contextual we can cache _part.contextual once.
				const part:IMediators =  _part.contextual(_owner.context);
				result = part.hasMediatorMapping(view["constructor"]) ?
					part.createMediator(view) : null;
				
				if (!result && _owner.parent)
				{
					return _owner.parent.mediators.createMediator(view);
				}
			}
			
			if (!result)
				throw new Error("IMediator for view " + view + " could not be found. " +
					"Please, make sure that it was added to module mediators.");
			
			return result;
		}
		
		public function destroyMediator(view:DisplayObject):IMediator
		{
			var result:IMediator;
			
			if (_owner.access == Access.GLOBAL)
			{
				return _owner.parent.mediators.destroyMediator(view);
			}
			else
			{
				result = _part.contextual(_owner.context).destroyMediator(view);
				
				if (!result && _owner.parent)
					return _owner.parent.mediators.destroyMediator(view);
			}
			return result;
		}
		
		public function hasMediator(view:DisplayObject):IMediator
		{
			var result:IMediator;
			
			if (_owner.access == Access.GLOBAL)
			{
				return _owner.parent.mediators.hasMediator(view);
			}
			else
			{
				result = _part.contextual(_owner.context).hasMediator(view);
				
				if (!result && _owner.parent)
					return _owner.parent.mediators.hasMediator(view);
			}
			return result;
		}
		
		public function hasMediatorMapping(view:Class):Boolean
		{
			var result:Boolean = false;
			
			if (_owner.access == Access.GLOBAL)
			{
				return _owner.parent.mediators.hasMediatorMapping(view);
			}
			else
			{
				result = _part.contextual(_owner.context).hasMediatorMapping(view);
				
				if (!result && _owner.parent)
					return _owner.parent.mediators.hasMediatorMapping(view);
			}
			return result;
		}
	}
}